/*
dart语法学习
 */

void main() {
  var i = 10.2;
//  var int =3; //int可以作为变量名
//  print('$i,$int\n');//单值时可以省略${变量}形式，直接使用$变量
  var s = '你好呀ddf\n';
  print(s);
  var kk; //没有初始化的变量默认值为null，在dart中一切都为对象，包括简单类型
  print(kk);
  // String -> int
  var one = int.parse('1');
  assert(one == 1); //断言失败则出错

// String -> double
  var onePointOne = double.parse('1.1');
  assert(onePointOne == 1.1);

// int -> String
  String oneAsString = 1.toString();
  assert(oneAsString == '1');

// double -> String
  String piAsString = 3.14159.toStringAsFixed(2);
  assert(piAsString == '3.14');
//  strTest();
//  bolTest();
//  listTest();
//  mapTest();
//  method(2, "sd"); //也可以不添加命名参数
//  method(1, "d", k: 2, c: 1); //携带命名参数,可不按顺序调用，指定参数名就可以
//  m2(1, 2); //可选参数必须按顺序传入
//  m3();
//  m4();
//  var p = 2;
//  nm(p);
//  print('p是$p'); //p任然是2
  try {
    ex();
  } on Exception catch (q) {
    if (q is Exception) {
      print('true');
    }
    print('on$q');
  } catch (e) {
    print('其他捕获');
  }
}

strTest() {
  //单引号和双引号都可以用
  var s = "sd水电费sd" "sd" 's'; //实现字符串自动拼接
  //或者
  var s2 = 'sd' + 'sd' + "sd";
  print(s + ',' + s2); //在方法调用里则必须要用+号来连接
  var e = '1';
  assert(e == '1'); // == 操作符判断两个对象的内容是否一样。 如果两个字符串包含一样的字符编码序列， 则他们是相等的。

  //使用三个单引号或者双引号也可以 创建多行字符串对象：
  var s4 = '''
You can create
multi-line strings like this one.
''';

  var s3 = """This is also a
multi-line string.""";

  //使用r前缀创建原始字符串(即写什么样就是什么样)
  var ys = r'ssd\n';
  print(ys);
}

bolTest() {
  var name = 'Bob';
  //只可判断bool布尔类型，不可判断其他类型
//  if (name) {
//    // Prints in JavaScript, not in Dart.
//    print('You have a name!');
//  }
}

///list练习
listTest() {
  var list = [1, 2, 3];
  print(list.length);
  list.add(2);
  print(list.length);
  const l2 = [];
//  l2.add(1);//不能修改常量
}

///文档注释
var i = 0;

///文档注释
///返回值啥也不写
///返回那就是动态的
///也就说不定返回啥
///指定了则就固定了
///map练习
void mapTest() {
  var gifts = {
// Keys      Values
    'first': 'partridge',
    'second': 'turtledoves',
    'fifth': 'golden rings'
  };

  var nobleGases = {
// Keys  Values
    2: 'helium',
    10: 'neon',
    18: 'argon',
  };

  var mp = Map(); //构造map方式1
  var mp2 = new Map(); //构造map方式2

  //添加键值对，键的类型可以不一样
  mp['na'] = 1;
  mp[1] = 1;
  print(mp);
  //取值
  print(mp['na']);
  print(mp['a']); //取不到返回null
  print(mp.length);
  print(mp2.length);
  mp['na'] = 3;
  print(mp);
}

///指定参数类型，调用是会检查类型是否匹配
///必须参数调用是必须都传入，此例中即a，b参数不可空
///{类型 变量名...} 命名参数,可任意数量个
method(int a, String b, {int c, int k}) {
  print(a);
  print(b);
  print(c);
  print(k); //无传入则为null
}

/////不支持这样重载
//method(){
//
//}

///中括号为可选参数，可传可不传
m2(int i, [int k, String d]) {}

///在定义方法的时候，可以使用 = 来定义可选参数的默认值。
///默认值只能是编译时常量。 如果没有提供默认值，则默认值为 null。
///只有命名参数和可选参数才可以使用默认值，必须参数不可以
m3([int i = 3]) {
  print('默认值：' + i.toString());
}

///默认值可有可无
m4({int i = 1, int j}) {
  if (i != null) {
    print('判断'); //因为有默认值，所以不为null，要判断是否为传入参数就必须判断自己的默认值
  }
  print('默认值：' + i.toString() + j.toString());
}

/// list 或者 map 作为默认值
void doStuff(
    {List<int> list = const [1, 2, 3],
    Map<String, String> gifts = const {
      'first': 'paper',
      'second': 'cotton',
      'third': 'leather'
    }}) {
  print('list:  $list');
  print('gifts: $gifts');
}

///匿名方法
///
nm(int o) {
  var list = ['apples', 'oranges', 'grapes', 'bananas', 'plums'];
  list.forEach((i) {
    print(list.indexOf(i).toString() + ': ' + i);
  });
  //lamuda 匿名函数
  o += 2;
  print('o是$o');
  var mk = (i) => {i = i + 2};
  int j = 5;
  mk(j);
  print(j); //j任然是5，是值传递
}

///异常测试
ex() {
  ///可以抛出任意类型
//  throw 'sds';
  try {
    throw Exception("sd");
  } catch (e, s) {
    print(e.toString()); //异常对象
    print(s); //异常栈
    rethrow; //重新抛出异常
  }
}

ctes() {
  var point = Point();
  Point.fromJso({'x': 2});
}

///class test

class Point {
  num x;
  num y;

  // Syntactic sugar for setting x and y
  // before the constructor body runs.
//  Point(this.x,this.y);

  Point(); //无参构造函数

  // 命名构造函数
  Point.fromJso(Map json) {
    x = json['x'];
    y = json['y'];
  }
}
